<?php

namespace App\Http\Controllers\Web\Enroll;

use App\App\Services\StorageService;
use App\Entities\Activity;
use App\Events\ActivityPaused;
use App\Events\ActivityStarted;
use App\Events\EnrollAudited;
use App\Exceptions\ExceptionCode;
use App\Http\Controllers\Controller;
use App\Models\Activity\ActivityService;
use App\Models\Enroll\Enroll;
use App\Models\Enroll\EnrollRepository;
use App\Models\Enroll\EnrollService;
use App\Models\Enroll\Parser;
use App\Models\Resource\Resource;
use App\Models\VoteCandidate\VoteCandidateService;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use League\Flysystem\Exception;
use Maatwebsite\Excel\Facades\Excel;

class EnrollController extends Controller
{

    /**
     * 展示报名列表
     *
     * @param Request       $request
     * @param EnrollService $enrollService
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function enrollList(
        Request $request,
        EnrollService $enrollService,
        StorageService $storageService,
        ActivityService $activityService
    )
    {
        $activity_id = $request->query->get('activities_id');
        $activity = $activityService->findOne($activity_id);
        $model_rule = $activity->model->rule;

        if ($model_rule == 'vote') {
            $activity_rule = json_decode($activity->rule, true);
            if (empty($activity_rule)) {
                return $this->respondJson(['code' => ExceptionCode::GENERAL, 'massage' => '请关联报名']);
            }
            if (Arr::get($activity_rule, 'relevanceEnrollOn') == 'on') {
                $request->query->set('activities_id', $activity_rule['relevanceEnroll']);
            }
        }

        $data = $enrollService->getEnrollServicePageList($request);

        foreach ($data['rows'] as &$item) {

            $enroll_info = $enrollService->find(['id' => $item['id']]);
            $parser = new Parser($enroll_info);
            foreach ($item['content'] as &$url) {
                if (Str::startsWith($url, ['alioss:'])) {
                    $url = $storageService->tomedia($url);
                    $url = str_replace("oss-cn", "img-cn", $url);
                } elseif (false === strpos($url, '.')) {
                    $url = Resource::where('resource_id', $url)->value('resource_url');
                    if (empty($url)) {
                        $url = 'has-no-video';
                    }
                }
            }
            $item['contents'] = $item['content'];
            $item['groups'] = $activity['groups'];
            $item['details'] = $parser->toCandidateContent(false);
        }
        unset($item);
        return $this->respondJson($data);
    }

    /**
     * 报名删除
     *
     * @param Request          $request
     * @param EnrollRepository $enrollRepository
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function enrollDelete(Request $request, EnrollRepository $enrollRepository)
    {
        $input = $request->request->all();
        $id = $input['id'];

        if (empty($id)) {
            return $this->respondJson([
                'message' => 'ID不存在',
            ]);
        }

        $ids = json_decode($id);

        if (!is_array($ids)) {
            $data = $enrollRepository->findById($id);
            if (!$data) {
                return $this->respondJson([
                    'message' => '数据不存在',
                ]);
            }
            $ids = [$id];
        }

        $res = $enrollRepository->softDelete($ids);
        if ($res) {
            return $this->respondJson([
                'message' => '删除成功',
            ]);
        } else {
            return $this->respondJson([
                'message' => '删除失败！请重新删除',
            ]);
        }
    }

    protected function getCandidateContent(Enroll $enroll)
    {
        $parser = new Parser($enroll);

        $content = $parser->makeExtFields();

        foreach (['姓名', '手机号', '时间'] as $key) {
            if (isset($content[$key])) {
                $newKey = '--' . $key . '--';
                $content[$newKey] = $content[$key];
                unset($content[$key]);
            }
        }

        return $content;
    }

    /**
     * 导出报名数据
     *
     * @param Request         $request
     * @param EnrollService   $enrollService
     * @param ActivityService $activityService
     *
     * @return mixed
     */
    public function export(Request $request, EnrollService $enrollService, ActivityService $activityService)
    {
        $activity_id = $request->query->get('activity_id');
        $dataRes = $enrollService->findAll(['activities_id' => $activity_id]);
        $activity = $activityService->findOne($activity_id);
        if (empty($dataRes->toArray()) || empty($activity)) {
            # return $this->respondJson(['code'=>ExceptionCode::GENERAL,'massage'=>'报名活动不存在']);
            return Excel::create('empty', function ($excel) {
                $excel->sheet('sheet1', function ($sheet) {
                    $sheet->fromArray([]);
                });
            })->download('xlsx');
        }
        //组装数据
        foreach ($dataRes as &$list) {
            $candidateContent = $this->getCandidateContent($list);
            $list = $list->toArray();
            $res['姓名'] = $list['name'];
            $res['手机号'] = $list['mobile'];
            $res['时间'] = $list['created_at'];
            $res = array_merge($res, $candidateContent);
            $data[] = $res;
        }

        $filename = '【' . $activity->name . '】报名者' . date('Y-m-d H:i:s');

        Excel::create($filename, function ($excel) use ($data) {
            $excel->sheet('报名者', function ($sheet) use ($data) {
                $sheet->fromArray($data);
            });
        })->download('xlsx');
    }

    /*
     * 审核
     */
    public function edit(
        Request $request,
        EnrollService $enrollService,
        VoteCandidateService $voteCandidateService,
        ActivityService $activityService
    )
    {
        $id = $request->input('id');
        $act_id = $request->input('act_id');
        $status = $request->input('status');
        $group_id = $request->input('groupid', '');
        if (!$id) {
            return $this->respondJson(['code' => ExceptionCode::GENERAL, 'message' => '参数错误']);
        }

        $contents = $enrollService->find([['id', '=', $id]]);
        if (Enroll::CHECK_PASS == $contents->status) {
            return $this->respondJson(['code' => ExceptionCode::GENERAL, 'message' => '不可重复审核']);
        }
        $resourceIds = [];

        foreach ($contents->content as $content) {
            if (!Str::startsWith($content, ['alioss:'])) {
                $resourceIds[] = $content;
            }
        }

        $resource = Resource::query()->whereIn('resource_id', $resourceIds);

        if ($resource->count() != count($resourceIds)) {
            return $this->respondJson(['code' => ExceptionCode::GENERAL, 'message' => '转码还没完成，请稍等']);
        }
        $coverUrl = '';
        if ($row = $resource->first()) {
            $coverUrl = $row->cover_url;
        }
        $msg = '';
        DB::beginTransaction();
        try {
            $enrollService->modify(['status' => $status], ['id' => $id]);
            if ($status == Enroll::CHECK_PASS) {
                //关联报名到投票
                $this->_addEnrollData(
                    $group_id,
                    $act_id,
                    $id,
                    $enrollService,
                    $voteCandidateService,
                    $activityService,
                    $coverUrl
                );
                $msg = '审核通过';
            } else {
                $msg = '审核不通过';
            }
            DB::commit();

            return $this->respondJson(['message' => $msg]);
        } catch (Exception $e) {
            DB::rollback();

            return $this->respondJson(['code' => ExceptionCode::GENERAL, 'message' => '审核失败']);
        }

    }

    private function _enrollDataFormat($group_id, $act_id, $enroll_info, $activity_rule, $coverUrl, $code)
    {
        $type = 0;
        if (!empty($activity_rule['upContentType'])) {
            $type = ($activity_rule['upContentType'] == 'image') ? 1 : (($activity_rule['upContentType'] == 'voice') ? 2 : 3);
        }

        if (null == $group_id) {
            $group_id = '';
        }

        $parser = new Parser($enroll_info);
        $res['activity_id'] = $act_id;
        $res['title'] = $enroll_info->name;
        $res['content'] = $parser->parseEnrollsToJson();
        $res['order_id'] = 0;
        $res['group_id'] = $group_id;
        $res['type'] = $type;//1、图片 2、音频 3、视频 4、外链
        $res['cover_url'] = !empty($parser->getCoverUrl()) ? $parser->getCoverUrl() : $coverUrl;
        $res['resource_url'] = $parser->getResourceUrl();
        $res['resource_id'] = $parser->getResourceUrl();
        $res['code'] = intval($code) + 1;
        $res['from'] = Enroll::FROM_ENROLLS_JSON;

        return $res;
    }

    /**
     * 持久化报名数据
     *
     * @param $group_id
     * @param $act_id
     * @param $id
     * @param $enrollService
     * @param $voteCandidateService
     * @param $activityService
     *
     * @return bool
     */
    private function _addEnrollData($group_id, $act_id, $id, EnrollService $enrollService,
                                    VoteCandidateService $voteCandidateService, ActivityService $activityService, $coverUrl)
    {
        $enroll_info = $enrollService->find(['id' => $id]);
        $activity = $activityService->findOne($enroll_info->activities_id);
        $activity_rule = json_decode($activity->rule, true);
        if (!is_array($activity_rule)) {
            return false;
        }
        $code = $voteCandidateService->getMaxCode($act_id);
        $enrollFormatData = $this->_enrollDataFormat($group_id, $act_id, $enroll_info, $activity_rule, $coverUrl, $code);
        $res = $voteCandidateService->createCandidate($enrollFormatData);

        $entity = Activity::with('template')->where('id', $act_id)->first();
        $template = isset($entity->template->template) ? $entity->template->template : '';

        switch ($template) {
            case "poll":
                event(new EnrollAudited($res));
                break;
            case "default":
            case "vote-screen":
            case "multiple-vote":
            case "ballot":
                event(new ActivityPaused($act_id), new ActivityStarted($act_id));
                break;
        }

        return $res;
    }

    /*
     * 批量审核
     */
    public function editBatch(
        Request $request,
        EnrollService $enrollService,
        VoteCandidateService $voteCandidateService,
        ActivityService $activityService
    )
    {
        $ids = $request->input('id');
        $act_id = $request->input('act_id');
        $status = $request->input('status');

        if (!is_array($ids) && count($ids)) {
            return $this->respondJson(['code' => ExceptionCode::GENERAL, 'message' => '参数错误']);
        }
        $res = $enrollService->update(['status' => $status], $ids);
        if ($res) {
            if ($status == Enroll::CHECK_PASS) {
                foreach ($ids as $id) {
                    //关联报名到投票
                    $this->_addEnrollData(
                        '',
                        $act_id,
                        $id,
                        $enrollService,
                        $voteCandidateService,
                        $activityService
                    );
                }
                $msg = '批量审核通过';
            } else {
                $msg = '批量审核不通过';
            }
        } else {
            return $this->respondJson(['code' => ExceptionCode::GENERAL, 'message' => '审核失败']);
        }

        return $this->respondJson(['message' => $msg]);
    }
}
